#!/usr/bin/python

###############################################################
#
# Update Copyright - Script that takes in a file list and, if
#                    applicable, updates the copyright date of
#                    each file
#
#
# Authors: Eric Stouch
#          Keith Edmister
#
###############################################################

import fileinput
import re
import subprocess
import logging
import sys
import getopt
import os
import pdb

# Set up debugger logging, syntax is logging.debug("print statements")
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

#############################################################
# Function main
# Inputs: argv
# Outputs None
# Description: main function, receives command line arguments
#############################################################
def main(argv):
    file = ''
    fileList = []
    scriptName = os.path.basename(__file__)
    usageString = "usage: " + scriptName + " { -f <fileList> | -a | -h }"

    try:
        opts, args = getopt.getopt(argv,'f:ah', ['fileList=', 'autoUpdate', 'help'])
    except getopt.GetoptError:
        print usageString
        sys.exit(2)
    for opt, arg in opts:
        if opt in ("-a", "--autoUpdate"):
            fileList = genAcFileList()
            processFileList(fileList)
        elif opt in ("-h", "--help"):
            moreInfo = """\nNAME
    {sub} - update copyright of all files in a filelist

SYNOPSIS
    This script will take in a list of files, process them looking for out of date copyright and update the year accordingly.

    Manual Instructions:
    In an accurev workspace get the modified files and put them in a file list (full paths needed)
    Then, pass the file list into updateCopyright.py

    Auto Instructions:
    The autoUpdate option will generate a file list based on the modified files in the current accurev workspace

USAGE:
    {usage}

BASIC OPTIONS:

    -f, --fileList                        Takes in a file list. Create the
                                          fileList and run the script in
                                          the working directory

    -a, --autoUpdate                      Generates a file list from modified
                                          files in accurev current workspace

OPTIONAL ARGUMENTS:
    -h, --help                            Help flag. Will show usage and
                                          examples of how to use the script

EXAMPLES:
    Manual:        updateCopyright.py -f fileList (where fileList contains a list of files with full paths)
    AutoUpdate:    updateCopyright.py -a""".format(sub=scriptName, usage=usageString)

            print moreInfo
        elif opt in ("-f", "--fileList"):
            file = arg
            try:
                # Open the fileList of modified files
                with open(file, "r") as fileList:
                    processFileList(fileList)
            except:
                print "ERROR: Could not find file \'" + arg + "\'"
                print usageString

    # If no file list is provided, print usage
    if len(sys.argv) == 1:
        print usageString + ", use \'-h\' for more info"

    sys.exit()
#end main

#############################################################
# Function processFileList
# Inputs: fileList - takes in a file list to process
# Outputs: None
# Description: takes in a file list and invokes the updateYear
#              function passing each individual file.
#############################################################
def processFileList( fileList ):
    print "\nChecking for expired copyright dates..."

    # Get the current date info
    currYear = subprocess.check_output("date +%Y", shell=True)
    currYear = currYear.strip('\n')

    totalCount = 0
    modifiedCount = 0
    # For all files in the list, pass each file as a string to updateYear
    for line in fileList:
        line = line.strip('\n')
        logging.debug("Checking " + line)
        changed = updateYear(line, currYear)
        if (changed == True) :
            modifiedCount = modifiedCount + 1
        totalCount = totalCount + 1

    print "\n =========== Copyright Updated ==========="
    print "|Checked files: " + str(totalCount)
    print "|Files with copyright updated: " + str(modifiedCount)
    print " ========================================="

# end processFileList

#############################################################
# Function updateYear
# Inputs: filename - A single file in the file list
# Outputs: modified (boolean)
# Description: takes in a file list and modifies the copyright
#              date of all files in that file list
#############################################################
def updateYear( filename, currYear ):
    regex = "(?i)Copyright.?\(C\).*?(\d+)-?(\d*)?"

    modified = False
    invalidDate = "WARNING: Invalid copyright date in " + filename + ". Copyright date not updated."

    # inplace allows for text change in place
    f = fileinput.FileInput(filename, inplace=True)

    # For each file, see if copyright needs updated
    for line in f:
        match = re.search(regex, line)

        if (match):
            date1 = match.group(1)
            date2 = match.group(2)

            # If we have a range and the second year does not equal current year
            if ( date2 and (date2 != currYear) ):
                if ( len(date2) == 2 or len(date2) == 4):
                    line = re.sub(date2, currYear, line)
                    modified = True
                else:
                    logging.debug(invalidDate)

            # If we DON'T have a range and the year does not equal current year
            elif ( not(date2) and (date1 != currYear) ):
                if (len(date1) == 4):
                    # Create a range
                    date1 += "-" + currYear
                    line = re.sub(match.group(1), date1, line)
                    modified = True
                else:
                    logging.debug(invalidDate)
            # The ',' prints the line without a newline char
            print line,
        else:
            print line,
    f.close()

    # return the modified boolean to keep track of count
    return modified
# end updateYear

# #############################################################
# Function genAcFileList
# Inputs: None
# Outputs: Returns accurev file list
# Description: generates an accurev file list and returns
#############################################################
def genAcFileList():

    DEVNULL = open(os.devnull, 'wb')
    # Get the top directory
    topDir = subprocess.check_output("accurev info | grep Top | cut -d : -f2 | sed -e 's/^[ \t]*//'", stderr=DEVNULL,  shell=True)
    topDir = topDir.strip('\n')

    # If this command returns an empty string, there is a good chance we are not in an accuRev workspace, or not logged in
    if (topDir != ""):

        # Create file list with local modified files and modified default group
        genFileList = subprocess.check_output("accurev stat -d | cut -d ' ' -f1", stderr=DEVNULL, shell=True) + subprocess.check_output("accurev stat -m | cut -d ' ' -f1", stderr=DEVNULL, shell=True)
        genFileList = genFileList.split()

        # Accurev generates different file paths in top dir vs sub dirs
        if (topDir == os.getcwd()):
            replace = "\."
        else:
            replace = "/\."

        fullPathList = []
        for line in genFileList:
            fullPathList.append(re.sub(replace, topDir, line, 1))


        # Deduplicate items in the list
        genFileList = list(set(fullPathList))

        return genFileList
    else:
        try:
            subprocess.check_output("accurev info | grep 'not logged in'", stderr=DEVNULL, shell=True)
            print "ERROR: Accurev login required"
            sys.exit(1)
        except:
            print "ERROR: Can't determine the Top directory of the workspace. Run 'ac info' for more info"
            sys.exit(1)
# end genAcFileList


if __name__ == "__main__":
    main(sys.argv[1:])
